import type { Metadata } from "next"
import Link from "next/link"
import { createSupabaseAdminClient } from "@/lib/supabase/admin"
import { sanitizeEntryContent } from "@/lib/sanitize"
import { SharedEntryContent } from "./shared-entry-content"

interface SharedPageProperties {
  params: Promise<{ token: string }>
}

interface SharedHighlightData {
  highlightedText: string
  textOffset: number
  textLength: number
  textPrefix: string
  textSuffix: string
}

interface SharedEntryRow {
  id: string
  entry_id: string
  expires_at: string | null
  note: string | null
  note_is_public: boolean
  view_count: number
  expiry_interval_days: number
  highlighted_text: string | null
  highlight_text_offset: number | null
  highlight_text_length: number | null
  highlight_text_prefix: string | null
  highlight_text_suffix: string | null
  entries: {
    id: string
    title: string | null
    url: string | null
    author: string | null
    summary: string | null
    content_html: string | null
    published_at: string | null
    enclosure_url: string | null
    feeds: {
      title: string | null
    }
  }
}

async function fetchSharedEntry(token: string) {
  const adminClient = createSupabaseAdminClient()

  const { data, error } = await adminClient
    .from("shared_entries")
    .select(
      "id, entry_id, expires_at, note, note_is_public, view_count, expiry_interval_days, highlighted_text, highlight_text_offset, highlight_text_length, highlight_text_prefix, highlight_text_suffix, entries!inner(id, title, url, author, summary, content_html, published_at, enclosure_url, feeds!inner(title))"
    )
    .eq("share_token", token)
    .maybeSingle()

  if (error || !data) return null

  const row = data as unknown as SharedEntryRow

  if (row.expires_at && new Date(row.expires_at) < new Date()) {
    return { expired: true as const }
  }

  let highlightData: SharedHighlightData | null = null
  if (
    row.highlighted_text &&
    row.highlight_text_offset !== null &&
    row.highlight_text_length !== null
  ) {
    highlightData = {
      highlightedText: row.highlighted_text,
      textOffset: row.highlight_text_offset,
      textLength: row.highlight_text_length,
      textPrefix: row.highlight_text_prefix ?? "",
      textSuffix: row.highlight_text_suffix ?? "",
    }
  }

  const publicNote = row.note_is_public && row.note ? row.note : null

  const expiryIntervalDays = row.expiry_interval_days ?? 7
  const newExpiresAt = new Date(
    Date.now() + expiryIntervalDays * 24 * 60 * 60 * 1000
  ).toISOString()

  adminClient
    .from("shared_entries")
    .update({
      view_count: row.view_count + 1,
      last_viewed_at: new Date().toISOString(),
      expires_at: newExpiresAt,
    })
    .eq("id", row.id)
    .then(() => {})

  return { expired: false as const, entry: row.entries, highlightData, publicNote }
}

export async function generateMetadata({
  params,
}: SharedPageProperties): Promise<Metadata> {
  const { token } = await params
  const result = await fetchSharedEntry(token)

  if (!result || result.expired) {
    return { title: "shared entry — asa.news" }
  }

  return {
    title: `${result.entry.title ?? "untitled"} — asa.news`,
    description: result.entry.summary?.slice(0, 200) ?? undefined,
    openGraph: {
      title: result.entry.title ?? "shared entry",
      description: result.entry.summary?.slice(0, 200) ?? undefined,
      siteName: "asa.news",
    },
  }
}

export default async function SharedPage({ params }: SharedPageProperties) {
  const { token } = await params
  const result = await fetchSharedEntry(token)

  if (!result) {
    return (
      <div className="mx-auto max-w-2xl px-6 py-16 text-center">
        <h1 className="mb-4 text-text-primary">shared entry not found</h1>
        <p className="text-text-secondary">
          this shared link is no longer available or has been removed.
        </p>
      </div>
    )
  }

  if (result.expired) {
    return (
      <div className="mx-auto max-w-2xl px-6 py-16 text-center">
        <h1 className="mb-4 text-text-primary">this share has expired</h1>
        <p className="text-text-secondary">
          shared links expire after a set period. the owner may share it again if needed.
        </p>
      </div>
    )
  }

  const entry = result.entry
  const sanitisedHtml = sanitizeEntryContent(entry.content_html || entry.summary || "")
  const formattedDate = entry.published_at
    ? new Date(entry.published_at).toLocaleDateString("en-GB", {
        day: "numeric",
        month: "long",
        year: "numeric",
      })
    : null

  return (
    <div className="mx-auto max-w-2xl px-6 py-8">
      <article>
        <h1 className="mb-2 text-lg text-text-primary">{entry.title}</h1>
        <div className="mb-6 text-text-dim">
          {entry.feeds?.title && <span>{entry.feeds.title}</span>}
          {entry.author && <span> &middot; {entry.author}</span>}
          {formattedDate && <span> &middot; {formattedDate}</span>}
        </div>
        {result.publicNote && (
          <blockquote className="mb-6 border-l-2 border-border pl-4 text-text-secondary italic">
            {result.publicNote}
          </blockquote>
        )}
        {entry.enclosure_url && (
          <div className="mb-4 border border-border p-3">
            <audio
              controls
              preload="none"
              src={entry.enclosure_url}
              className="w-full"
            />
          </div>
        )}
        <SharedEntryContent
          sanitisedHtml={sanitisedHtml}
          highlightData={result.highlightData}
        />
      </article>
      <footer className="mt-12 border-t border-border pt-4 text-text-dim">
        <p>
          shared from{" "}
          <Link
            href="/"
            className="text-text-secondary transition-colors hover:text-text-primary"
          >
            asa.news
          </Link>
        </p>
        {entry.url && (
          <p className="mt-1">
            <a
              href={entry.url}
              target="_blank"
              rel="noopener noreferrer"
              className="text-text-secondary transition-colors hover:text-text-primary"
            >
              view original
            </a>
          </p>
        )}
      </footer>
    </div>
  )
}
